package com.lightjet.macross.base.awf.controller;

import com.lightjet.macross.base.awf.domain.BizProcessConfig;
import com.lightjet.macross.base.awf.dto.NodeDefDTO;
import com.lightjet.macross.base.awf.dto.ProcDefDTO;
import com.lightjet.macross.base.awf.dto.ProcInstDTO;
import com.lightjet.macross.base.awf.dto.ProcModelDTO;
import com.lightjet.macross.base.awf.service.BizProcessConfigService;
import com.lightjet.macross.base.awf.service.ProcessService;
import com.lightjet.macross.base.feign.api.controller.PrincipalController;
import com.lightjet.macross.common.dto.ResponseDTO;
import com.lightjet.macross.common.util.RespUtil;
import io.netty.util.internal.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.java.Log;
import org.apache.ibatis.annotations.Delete;
import org.checkerframework.checker.guieffect.qual.PolyUIType;
import org.springframework.context.annotation.Scope;
import org.springframework.data.domain.Example;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * @author : lijia
 * @version : 1.0 2020-03-23 09:03
 * description : 流程模块管理控制器
 */

@RestController
@RequestMapping("/api/admin")
@Scope("request")
@Log
@Api(tags="AWF业务流程服务-管理相关接口集")
public class AdminController extends PrincipalController {

    @Resource
    private ProcessService processService;

    @Resource
    private BizProcessConfigService bizProcessConfigService;

    @RequestMapping(value="/model/list", method = {RequestMethod.GET})
    @ApiOperation(value = "流程模型查询接口", notes = "根据流程模型名称模糊查询流程模型列表")
    public ResponseDTO<List<ProcModelDTO>> ModelList(@ApiParam(name="modelname",value = "模型名称",type="query") String modelname)
    {
        return RespUtil.CreateOK(processService.GetModelList(StringUtil.isNullOrEmpty(modelname)?"":modelname));
    }

    @PostMapping(value="/model",consumes = "application/json")
    @ApiOperation(value = "流程模型新增及复制接口", notes = "根据流程模型数据传输类对象Json进行创建或复制（对象ID为空表示新增，对象ID不为空表示已此ID模型对象进行复制）")
    public ResponseDTO<ProcModelDTO> ModelCreate(
            @ApiParam(name="model",value = "模型数据传输类对象Json",required = true,type="body") @RequestBody ProcModelDTO model)
    {
        if(StringUtil.isNullOrEmpty(model.getId()))//id为空表示新增
        {
            return RespUtil.FromResultDTO(processService.CreateModel(model.getName(),model.getKey(),model.getMetaInfo(),model.getCategory()));
        }
        else //id不为空表示模型拷贝自此id
        {
            return RespUtil.FromResultDTO(processService.CopyModel(model.getId(),model.getName(),model.getKey(),model.getMetaInfo(),model.getCategory()));
        }
    }

    @DeleteMapping(value = "/model")
    @ApiOperation(value = "流程模型删除接口", notes = "根据流程模型ID删除流程模型")
    public ResponseDTO<String> ModelDelete(@ApiParam(name="modelid",value = "模型ID",required = true,type="query") String modelid){
        return RespUtil.FromResultDTO(processService.DeleteModel(modelid));
    }

    @PostMapping(value = "/model/deploy")
    @ApiOperation(value = "流程模型发布接口", notes = "根据流程模型ID发布并部署该模型定义的流程")
    public ResponseDTO<String> ModelDeploy(@ApiParam(name="modelid",value = "模型ID",required = true,type="query") String modelid){
        return RespUtil.FromResultDTO(processService.DeployFromModel(modelid));
    }

    @GetMapping("/processconfig/list")
    @ApiOperation(value = "流程配置查询接口", notes = "根据流程定义ID查询流程配置数据集合(参数流程定义ID为空或为*代表查询全部)")
    public ResponseDTO<List<BizProcessConfig>> ProcessConfigList(@ApiParam(name="pdid",value = "流程定义ID",type="query") String pdid)
    {
        List<BizProcessConfig> list = new ArrayList<>();
        if(StringUtil.isNullOrEmpty(pdid) || "*".equals(pdid))
        {
            list = (bizProcessConfigService.FindAll());
        }
        else
        {
            BizProcessConfig query = new BizProcessConfig();
            query.setProcinstdefId(pdid);
            query.setIsenable(null);
            list = (bizProcessConfigService.FindAll(Example.of(query)));
        }
        Map<String,NodeDefDTO> nodeMap = processService.GetAllProcNodeDef(false).
                stream().collect(Collectors.toMap(NodeDefDTO::getNodedefkey, e-> e ,(v1, v2)-> v1));
        for(BizProcessConfig bizProcessConfig : list)
        {
            bizProcessConfig.setIsenabledisp(bizProcessConfig.getIsenable() == 1 ?"是":"否");
            NodeDefDTO node = nodeMap.get(bizProcessConfig.getNodedefId());

            bizProcessConfig.setNodedefname(node==null? bizProcessConfig.getNodedefId(): node.getNodedefname());
        }
        return RespUtil.CreateOK(list);
    }

    @PostMapping(value="/processconfig",consumes = "application/json")
    @ApiOperation(value = "流程配置创建接口", notes = "根据流程配置实体类对象Json创建流程配置")
    public ResponseDTO<BizProcessConfig> ProcessConfigCreate(
            @ApiParam(name="bizProcessConfig",value = "流程配置实体类对象Json",required = true,type="body") @RequestBody BizProcessConfig bizProcessConfig)
    {
        try {
            return RespUtil.CreateOK(bizProcessConfigService.CreateAndFlush(bizProcessConfig));
        }
        catch (Exception e)
        {
            return RespUtil.CreateError("新建流程配置项失败："+e.getMessage());
        }
    }

    @PutMapping(value="/processconfig",consumes = "application/json")
    @ApiOperation(value = "流程配置更新接口", notes = "根据流程配置实体类对象Json更新流程配置")
    public ResponseDTO<BizProcessConfig> ProcessConfigUpdate(
            @ApiParam(name="bizProcessConfig",value = "流程配置实体类对象Json",required = true,type="body") @RequestBody BizProcessConfig bizProcessConfig)
    {
        try {
            BizProcessConfig original = bizProcessConfigService.GetOne(bizProcessConfig.getId());
            original.setConfigtype(bizProcessConfig.getConfigtype());
            original.setConfigvalue(bizProcessConfig.getConfigvalue());
            original.setIsenable(bizProcessConfig.getIsenable());
            original.setMemo(bizProcessConfig.getMemo());
            original.setNodedefId(bizProcessConfig.getNodedefId());
            original.setProcinstdefId(bizProcessConfig.getProcinstdefId());
            return RespUtil.CreateOK(bizProcessConfigService.UpdateAndFlush(original));
        }
        catch (Exception e)
        {
            return RespUtil.CreateError("新建流程配置项失败："+e.getMessage());
        }
    }

    @DeleteMapping(value="/processconfig/batch",consumes = "application/json")
    @ApiOperation(value = "流程配置批量删除接口", notes = "根据流程配置实体类对象ID列表Json批量删除流程配置")
    public ResponseDTO<String> ProcessConfigBatchDelete(
            @ApiParam(name="ids",value = "流程配置实体类对象ID列表Json",required = true,type="body") @RequestBody List<Integer> ids) {
        try {
            bizProcessConfigService.DeleteInBatch(ids.stream().map(BizProcessConfig::new).collect(Collectors.toList()));
            return RespUtil.CreateOK();
        }
        catch (Exception e)
        {
            return RespUtil.CreateError("删除流程配置项失败："+e.getMessage());
        }
    }

    @GetMapping("/procdef/all")
    @ApiOperation(value = "全部流程定义查询接口", notes = "获取流全部程定义集合")
    public ResponseDTO<List<ProcDefDTO>> PorcessDefList()
    {
        return RespUtil.CreateOK(processService.GetProcessAllDefSet());
    }

    @GetMapping("/nodedef/all")
    @ApiOperation(value = "全部流程节点定义查询接口", notes = "获取全部流程节点定义集合(以流程最新版本为准)")
    public ResponseDTO<List<NodeDefDTO>> NodeDefList()
    {
        return RespUtil.CreateOK(processService.GetAllProcNodeDef(false));
    }


    @GetMapping("/nodedef/list")
    @ApiOperation(value = "流程节点定义查询接口", notes = "根据流程定义ID（或Key）获取流程节点定义集合（参数为Key查询最新版本）")
    public ResponseDTO<List<NodeDefDTO>> NodeProcDefList(
            @ApiParam(name="pdid",value = "流程定义ID",required = true,type="query") String pdid)
    {
        if (pdid.split(":").length <= 2) {
            pdid = processService.GetCurrentProcDef(pdid).getProcdefid();
        }
        return RespUtil.CreateOK(processService.GetTaskNodeDefSet(pdid));
    }

}
